iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
1
Mobile Development

小菜逼學習IOS系列 第 20

QRCode 學起來-倒數12天

  • 分享至 

  • xImage
  •  

QRCode

首先要在 Info.plist 加入相機使用權限,新增privacy-camera usage description

在 Main.Storyboard 拉個 view 和 button

回到 View Controller import AVFoundation(控制視聽設備、相機、影音等)及SafariServices(在App中使用Safari開啟網頁)

class還要再加上兩個Delegate:

AVCaptureMetadataOutputObjectsDelegate:用來捕捉並輸出數據的方法。

UINavigationControllerDelegate:彈出視窗,並可返回上一頁(就是代理NavigationController),在此是彈出相簿視窗。

再來使用AVCaptureSession(用於捕捉視訊及音訊,協調視訊及音訊的輸入及輸出)、AVCaptureVideoPreviewLayer(呈現Session捕捉的資料)

viewDidAppear 在完成視圖的初始外觀中涉及的所有圖形和動畫之後,將調用此方法

 override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
         setQRCodeScan()
        
    }
//掃QRCode的動作
func setQRCodeScan(){
        
        //實體化一個AVCaptureSession物件
        captureSesion = AVCaptureSession()
        
        //AVCaptureDevice可以抓到相機和其屬性
        guard let videoCaptureDevice = AVCaptureDevice.default(for: .video) else {return}
        let videoInput:AVCaptureDeviceInput
        do {
            videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice)
        }catch let error {
            print(error)
            return
        }
        if (captureSesion?.canAddInput(videoInput) ?? false ){
            captureSesion?.addInput(videoInput)
        }else{
            return
        }
        
        //AVCaptureMetaDataOutput輸出影音資料,先實體化AVCaptureMetaDataOutput物件
        let metaDataOutput = AVCaptureMetadataOutput()
        if (captureSesion?.canAddOutput(metaDataOutput) ?? false){
            captureSesion?.addOutput(metaDataOutput)
            
            //關鍵!執行緒處理QRCode
            metaDataOutput.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
            //metadataOutput.metadataObjectTypes表示要處理哪些類型的資料,處理QRCODE
            metaDataOutput.metadataObjectTypes = [.qr, .ean8 , .ean13 , .pdf417]
            
        }else{
            return
        }
        
        //用AVCaptureVideoPreviewLayer來呈現Session上的資料
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSesion!)
        //顯示size
        previewLayer.videoGravity = .resizeAspectFill
        //呈現在camView上面
        previewLayer.frame = camView.layer.frame
        //加入畫面
        view.layer.addSublayer(previewLayer)
        //開始影像擷取呈現鏡頭的畫面
        captureSesion?.startRunning()
    }

接著使用AVCaptureMetadataOutput物件辨識QRCode

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutputmetadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
        captureSesion?.startRunning()
        if let metadataObject = metadataObjects.first{
            
            //AVMetadataMachineReadableCodeObject是從OutPut擷取到barcode內容
            guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject else {return}
            //將讀取到的內容轉成string
            guard let stringValue = readableObject.stringValue else {return}
            //掃到QRCode後的震動提示
            AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
            //存取QRcodeURL
            QRCodeString = stringValue   
        }
    }

按下Button後利用present以safari開啟Label上顯示的URL:

//開啟網頁
    @IBAction func openWebButton(_ sender: Any) {
        let url = URL(string:QRCodeString)
        let safariVC = SFSafariViewController(url: url!)
        
        present(safariVC,animated: true ,completion: nil)
    }

上一篇
在Xcode中使用 XIB root view-倒數13天
下一篇
tableview + collectionview 蹦出新滋味 - 倒數11
系列文
小菜逼學習IOS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言